package com.blog.cloud.gateway.service;

import org.springframework.context.annotation.Bean;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import reactor.core.publisher.Mono;

// 关于反应式系统开启使用 Spring Security 方法级安全控制的示例代码
// 参考文章：https://docs.spring.io/spring-security/reference/reactive/authorization/method.html
public interface GatewayService {

    // 在这种情况下 hasRole 指的是 SpEL 评估引擎调用的 SecurityExpressionRoot 中的方法。
    @PreAuthorize("hasRole('USER')")
    @PostAuthorize("returnObject.owner == authentication.name")
    Mono<Account> readAccount(Long id);

    @PreAuthorize("hasRole('USER')")
    Flux<Account> findAccounts();

    @PreAuthorize("@func.apply(#account)")
    Mono<Account> post(Account account, Double amount);


    // @bean 指的是您定义的自定义组件，其中 apply 可以返回布尔值或 Mono<Boolean>，以指示授权决定。类似的 bean 可能是这样的
    @Bean
    public Function<Account, Mono<Boolean>> func() {
        return (account) -> Mono.defer(() -> Mono.just(account.getId().equals(12)));
    }
}
